:- module(tsv,[columns/2,value/6,flagged/3]).

/**
 * Some tools to parse eurostat tsv files
 */

:- use_module(t_record).

/**
 * Values in the tsv file, using
 * the information on the first line
 */
value(File,Dimensions,IndicesDim,I,V,F) :-
	columns(File,N),
	length(Rec,N),
	findall(Rec,t_record(File,Rec),[[TableSpec|Indices]|Records]),
	member([DimIDs|Values],Records),
	parse_table_spec(TableSpec,DimensionsSpec,IndicesDim),
	parse_dim(DimIDs,DimList),
	dimensions(DimensionsSpec,DimList,Dimensions),
	resp_member(Indices,Values,Indice,Value),
	flagged(Value,V2,F2),F=F2,V=V2, % hack to allow a particular lookup (+V,+F) to succeed without making concat_atom crash
	remove_trail_space(Indice,I).

/**
 * Parses a flagged value, gives '' otherwise
 */
flagged(Value,V,F) :-
	concat_atom([V,F],' ',Value),!.
flagged(Value,Value,'').


resp_member([H1],[H2],H1,H2) :- !.
resp_member([H1|_],[H2|_],H1,H2).
resp_member([_|T1],[_|T2],H1,H2) :-
	resp_member(T1,T2,H1,H2).


dimensions([],[],[]) :- !.
dimensions([Dimension|T1],[DimID|T2],[dimension(Dimension,DimID)|T3]) :-
	dimensions(T1,T2,T3).


parse_dim(DimIDs,List) :-
	concat_atom(List,',',DimIDs).


parse_table_spec(Spec,Dimensions,IndicesDim) :-
	concat_atom(List,',',Spec),
	reverse(List,[Last|R]),
	concat_atom([LastDim,IndicesDim],'\\',Last),
	reverse([LastDim|R],Dimensions).


columns(File,N) :-
	open(File,read,Stream),
	count_on_first_line(Stream,9,N),
	close(Stream).


count_on_first_line(Stream,Code,N) :-
	count_on_first_line(Stream,Code,1,N).
count_on_first_line(Stream,Code,T,N) :-
	get_code(Stream,C),
	((C=10,T=N,!);
	(C = Code -> (
			T2 is T+1,
			count_on_first_line(Stream,Code,T2,N)
		);
		(
			count_on_first_line(Stream,Code,T,N)
		))).

remove_trail_space(Atom,Atom) :-
	\+atom_concat(_,' ',Atom).
remove_trail_space(Atom,AtomC) :-
	atom_concat(T,' ',Atom),
	remove_trail_space(T,AtomC).

